<template>
	<a-upload
		v-model:file-list 	= 'myFileList'
		:name 				= 'fileName'
		:data            	= 'param'
		:list-type 			= 'mode'
		:show-upload-list 	= 'list'
		:action 			= "apiPrefix + api"
		:before-upload 		= 'beforeUpload'
		:disabled 			= 'disabled'
		@change 			= 'onChange'
		@preview 			= 'onPreview'
		:customRequest 		= 'customRequest'
		:headers 			= 'headers'
		:remove 			= 'remove'
		:multiple 			= 'multiple'
		:class 				= "{ 'upload-multiple-no' : !multiple }"
	>
		<template v-if="mode === 'picture-card'">
			<div class='f30' v-if='myFileList.length <= max && !disabled'>
				<loading-outlined v-if='loading'></loading-outlined>
				<plus-outlined></plus-outlined>
			</div>
		</template>
		<template v-else>
			<Button :label='label' :loading='loading' ghost mode='upload' size='small' :stop='false' :width='80'/>
		</template>
	</a-upload>
</template>

<script>
	import { ref, watch } from 'vue'
	import { Upload } from 'ant-design-vue'
	import { PlusOutlined, LoadingOutlined } from '@ant-design/icons-vue'
	import Unique from '@utils/unique'
	
	app.use(Upload)
	
	const Modal 		= $.lazy(()=>import('@antd/modal.vue'))
	const Button 		= $.lazy(()=>import('@antd/button.vue'))
	const Image 		= $.lazy(()=>import('@antd/image.vue'))
	
	const getType = f => ({
		img: { bool: f === 'image/jpeg' || f === 'image/png' || f === 'image/jpg' , msg: '图片文件' },
		pdf: { bool: f === 'application/pdf', msg:'PDF 文件'},
		word: { bool: f === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', msg:'word 文件'},
		excel: { bool: f === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || f ==='application/vnd.ms-excel', msg:'Excel 文件'}
	})
	
	export default{
		components:{
			LoadingOutlined,
			PlusOutlined,
			Modal,
			Button,
			Image
		},
		props:{
			value 			: [Array, String, Object],
			fileName 		: { type:String, defalut:'file'},
			name 			: String,
			label 			: String,
			form 			: Object,
			max				: { type:Number, default: 8 },
			fileType 		: { type:String, defalut: 'all' },
			way 			: { type:Number, default: 0 },
			param 			: Object,
			label 			: { type:String, default: '上传'},
			mode	 		: { type:String, default: 'picture-card'},
			list			: { type:Boolean, default: true },
			multiple 		: { type:Boolean, default: true },
			api 			: { type:String, default:({ way })=>{
				if( way === 1){
					return 'file/upload/flow'
				}else{
					return 'file/upload'
				}
			}},
			disabled		: Boolean,
			my 				: Boolean,
			id 				: String
		},
		emits:{
			change: null,
			blur:null,
			'update:value': null
		},
		setup(props, ctx){
			const ajax = ref({ })
			const myFileList = ref([])
			
			watch(()=>props.value, value =>{
				if( $fn.isArray(value) ){
					myFileList.value = value.map( (v,i) => ({  uid:i, status: 'done', url: v }) )
				}else if(value){
					myFileList.value = [{ uid:'0', status: 'done', url:value }]
				}else{
					myFileList.value = []
				}
			})
			
			const loading = ref(false)
			
			const customRequest = async res => {
				setTimeout(()=>{
					let value
					if(props.multiple){
						let fileList = myFileList.value
						fileList = Unique(fileList,'name')
						value = fileList.map( v => {
							v.status = 'done'
							return v.originFileObj
						} )
						myFileList.value = props.multiple ? fileList : [ fileList[fileList.length - 1] ]
					}else{
						myFileList.value = value = res?.file ? [ res?.file ] : [ ]
					}
					ctx.emit('update:value', value )
					ctx.emit('change', { fileName: props.fileName, api: $config.api() + props.api, files: value } )
				})
			}
			
			const removeFile = file => {
				setTimeout(()=>{
					myFileList.value.forEach((v,i)=>{
						if(file.uid === v.uid){
							myFileList.value.splice(i, 1)
						}
					})
				})
			}
			
			return {
				myFileList,
				loading,
				apiPrefix: $config.api(),
				onChange: props.my ? null : ({ file, fileList, event }) => {
					if(file?.status === 'uploading'){
						loading.value = true
					}else if(file?.status === 'done'){
						const res = file.response
						const { code, data, msg } = res
						if(code === 200){
							$fn.msg.success('上传成功')
							const value = data.filePath
							ctx.emit('update:value', value)
							ctx.emit('change', { value, data, model: name ? {[name]: value} : {} })
							// ctx.emit('change', $fn.getFormFormat({...props, formType:'upload', uploadData:data }) )
							myFileList.value = props.multiple ? fileList : [ file ]
						}else if(code === $config.noLoginCode || code === $config.LoginExpireCode){
							$fn.msg.error( msg )
							setTimeout(() => $fn.go('/login'), 200 )
						}else{
							$fn.msg.error(msg)
							removeFile(file)
						}
						loading.value = false
					}else if(file.status === 'error'){
						loading.value = false
						$fn.msg.error('上传失败')
					}
				},
				beforeUpload(file){
					const type = getType(file.type)
					if(props.fileType === 'excel'){
						const isOk = type.excel.bool;
						if (!isOk) {
							$fn.msg.warning(`仅允许上传${type.excel.msg}!`)
							ctx.emit('update:value', null )
							ctx.emit('change', null )
							setTimeout(()=>{
								myFileList.value = []
							})
						}
						return isOk
					}else if(props.fileType === 'img'){
						// 图片格式
						const isImg = ['image/jpeg', 'image/jpg', 'image/png' ].includes(file.type)
						if(!isImg){ 
							$fn.msg.warning('只能上传 jpg、png图片')
							removeFile(file)
							return false
						}
						// 图片大小
						const size = 10
						const isSize = file.size / 1024 / 1024 < size  // 10 M
						if(!isSize){ 
							$fn.msg.warning(`只允许上传小于 ${size} M 的图片`)
							removeFile(file)
							return false
						}
					}
					return true
				},
				onPreview(file){
					window.$imageModalRef().open({
						title 	: '图片预览',
						src 	: file.url
					})
				},
				headers : {
					Authorization: 'Bearer ' + $fn.getToken()
				},
				remove: file => {
					if($fn.hasArray(myFileList.value) && file?.error?.status === 200){
						customRequest(file)
					}else{
						// ctx.emit('update:value', myFileList.value )
						// ctx.emit('change', {} )
					}
					return true
				},
				customRequest: props.my ? customRequest : null
			}
		}
	}
</script>